Introduzione: Oltre le variabili semplici
Finora abbiamo lavorato con variabili che contengono un singolo valore (un numero, una stringa, un booleano). Tuttavia, nella programmazione reale spesso dobbiamo gestire collezioni di dati: liste di nomi, insiemi di numeri unici, tabelle di informazioni correlate. Python offre quattro strutture dati fondamentali per organizzare e manipolare dati complessi in modo efficiente.
- Liste (list): collezioni ordinate e modificabili che permettono duplicati
- Tuple (tuple): collezioni ordinate e immutabili che permettono duplicati
- Set (set): collezioni non ordinate e modificabili che NON permettono duplicati
- Dizionari (dict): collezioni di coppie chiave-valore, ordinate e modificabili
| Struttura | Ordinata | Modificabile | Duplicati | Accesso |
|---|---|---|---|---|
| Lista | ✅ Sì | ✅ Sì | ✅ Sì | Per indice |
| Tupla | ✅ Sì | ❌ No | ✅ Sì | Per indice |
| Set | ❌ No | ✅ Sì | ❌ No | Non indicizzato |
| Dizionario | ✅ Sì (dalla 3.7) | ✅ Sì | ❌ Chiavi uniche | Per chiave |
1. Liste (List)
📋Liste: la struttura più versatile
Le liste sono la struttura dati più utilizzata in Python. Sono collezioni ordinate e modificabili di elementi. Pensa a una lista come a un contenitore numerato dove ogni elemento ha una posizione precisa (indice).
1.1 Creare liste
# Lista vuota
lista_vuota = []
altra_vuota = list()
# Lista con elementi
frutti = ["mela", "banana", "arancia", "pera"]
numeri = [10, 20, 30, 40, 50]
mista = [1, "ciao", 3.14, True, None] # Tipi diversi!
# Lista da range
numeri_sequenza = list(range(1, 6)) # [1, 2, 3, 4, 5]
print(frutti) # ['mela', 'banana', 'arancia', 'pera']
print(len(frutti)) # 4 (numero di elementi)
Visualizzazione di una lista con indici
frutti = ["mela", "banana", "arancia", "pera"]
mela
banana
arancia
pera
Gli indici partono da 0!
1.2 Accedere agli elementi
frutti = ["mela", "banana", "arancia", "pera"]
# Accesso per indice (da 0)
primo = frutti[0] # "mela"
secondo = frutti[1] # "banana"
# Indici negativi (dall'ultimo elemento)
ultimo = frutti[-1] # "pera"
penultimo = frutti[-2] # "arancia"
print(f"Primo frutto: {primo}")
print(f"Ultimo frutto: {ultimo}")
# Modificare un elemento
frutti[1] = "kiwi"
print(frutti) # ['mela', 'kiwi', 'arancia', 'pera']
Se provi ad accedere a un indice che non esiste, Python solleva un errore:
frutti = ["mela", "banana"]
print(frutti[5]) # ERRORE! L'indice 5 non esiste
La lista ha solo 2 elementi (indici 0 e 1).
1.3 Slicing: selezionare porzioni di lista
Lo slicing permette di estrarre una sottolista usando la sintassi lista[inizio:fine:step].
numeri = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
# Sintassi: lista[inizio:fine] (fine escluso!)
primi_tre = numeri[0:3] # [0, 1, 2]
dal_terzo = numeri[3:] # [3, 4, 5, 6, 7, 8, 9]
fino_al_quinto = numeri[:5] # [0, 1, 2, 3, 4]
# Con step
pari = numeri[::2] # [0, 2, 4, 6, 8]
dispari = numeri[1::2] # [1, 3, 5, 7, 9]
# Invertire una lista
invertita = numeri[::-1] # [9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
# Porzione specifica
centrale = numeri[3:7] # [3, 4, 5, 6]
lista[inizio:fine:step]
- inizio: indice di partenza (incluso). Default: 0
- fine: indice finale (escluso). Default: fine lista
- step: incremento. Default: 1
1.4 Metodi delle liste
Aggiunge un elemento alla fine
lista.append(5)
Inserisce elemento in posizione
lista.insert(0, "nuovo")
Rimuove prima occorrenza
lista.remove("mela")
Rimuove e restituisce elemento
ultimo = lista.pop()
Svuota completamente la lista
lista.clear()
Restituisce indice di elemento
pos = lista.index("banana")
Conta occorrenze
n = lista.count(5)
Ordina lista (in place)
lista.sort()
Inverte ordine (in place)
lista.reverse()
Crea copia della lista
nuova = lista.copy()
Aggiunge elementi da altra lista
lista.extend([1, 2, 3])
# Creare playlist
playlist = ["Song A", "Song B", "Song C"]
print(f"Playlist iniziale: {playlist}")
# Aggiungere canzoni
playlist.append("Song D")
print(f"Dopo append: {playlist}")
# Inserire all'inizio
playlist.insert(0, "Intro")
print(f"Con intro: {playlist}")
# Rimuovere una canzone
playlist.remove("Song B")
print(f"Dopo remove: {playlist}")
# Prendere ultima canzone
ultima = playlist.pop()
print(f"Ultima canzone estratta: {ultima}")
print(f"Playlist ora: {playlist}")
# Ordinare alfabeticamente
playlist.sort()
print(f"Ordinata: {playlist}")
# Invertire ordine
playlist.reverse()
print(f"Invertita: {playlist}")
# Cercare una canzone
if "Song A" in playlist:
posizione = playlist.index("Song A")
print(f"Song A è alla posizione {posizione}")
# Numero di canzoni
print(f"Totale canzoni: {len(playlist)}")
1.5 Operazioni con liste
# Concatenazione
lista1 = [1, 2, 3]
lista2 = [4, 5, 6]
unione = lista1 + lista2 # [1, 2, 3, 4, 5, 6]
# Ripetizione
ripetuta = [0] * 5 # [0, 0, 0, 0, 0]
multipla = ["ciao"] * 3 # ['ciao', 'ciao', 'ciao']
# Membership (appartenenza)
numeri = [1, 2, 3, 4, 5]
print(3 in numeri) # True
print(10 in numeri) # False
print(10 not in numeri) # True
# Iterazione
for numero in numeri:
print(numero)
# List comprehension (avanzato ma utile!)
quadrati = [x**2 for x in range(1, 6)] # [1, 4, 9, 16, 25]
pari = [x for x in range(10) if x % 2 == 0] # [0, 2, 4, 6, 8]
# Assegnazione semplice: NON copia, ma crea un alias!
lista1 = [1, 2, 3]
lista2 = lista1 # lista2 punta alla STESSA lista!
lista2[0] = 999
print(lista1) # [999, 2, 3] - anche lista1 è cambiata!
# Copia corretta
lista1 = [1, 2, 3]
lista2 = lista1.copy() # Oppure: lista2 = lista1[:]
lista2[0] = 999
print(lista1) # [1, 2, 3] - lista1 non è stata modificata!
2. Tuple (Tuple)
🔒Tuple: liste immutabili
Le tuple sono molto simili alle liste, ma con una differenza cruciale: sono immutabili. Una volta create, non puoi modificarle, aggiungere o rimuovere elementi. Questo le rende più veloci e sicure per dati che non devono cambiare.
2.1 Creare tuple
# Tupla con parentesi tonde
coordinate = (10, 20)
persona = ("Mario", 30, "Roma")
colori = ("rosso", "verde", "blu")
# Tupla senza parentesi (packing)
punto = 5, 10
print(punto) # (5, 10)
# Tupla con un solo elemento (serve la virgola!)
singola = (5,) # Tupla
non_tupla = (5) # NON è una tupla, è solo il numero 5
# Tupla vuota
vuota = ()
altra_vuota = tuple()
# Creare tupla da lista
lista = [1, 2, 3]
tupla_da_lista = tuple(lista) # (1, 2, 3)
- Performance: Le tuple sono più veloci delle liste
- Sicurezza: Garantiscono che i dati non vengano modificati accidentalmente
- Chiavi dizionario: Le tuple (ma non le liste) possono essere usate come chiavi nei dizionari
- Unpacking: Perfette per restituire valori multipli da funzioni
2.2 Accedere agli elementi
persona = ("Mario", 30, "Roma", "Ingegnere")
# Accesso per indice (come le liste)
nome = persona[0] # "Mario"
eta = persona[1] # 30
ultimo = persona[-1] # "Ingegnere"
# Slicing (come le liste)
info_base = persona[:2] # ('Mario', 30)
# Unpacking: assegnare ogni elemento a una variabile
nome, eta, citta, lavoro = persona
print(f"{nome} ha {eta} anni e vive a {citta}")
# Unpacking parziale con *
primo, *resto, ultimo = (1, 2, 3, 4, 5)
# primo = 1, resto = [2, 3, 4], ultimo = 5
2.3 Operazioni con tuple
# Concatenazione
t1 = (1, 2, 3)
t2 = (4, 5, 6)
t3 = t1 + t2 # (1, 2, 3, 4, 5, 6)
# Ripetizione
ripetuta = (0,) * 5 # (0, 0, 0, 0, 0)
# Membership
coordinate = (10, 20, 30)
print(20 in coordinate) # True
# Metodi disponibili (solo 2!)
numeri = (1, 2, 2, 3, 2, 4)
print(numeri.count(2)) # 3 (quante volte appare 2)
print(numeri.index(3)) # 3 (indice del primo 3)
# Iterazione
for valore in coordinate:
print(valore)
# NON puoi modificare una tupla
tupla = (1, 2, 3)
# tupla[0] = 999 # ERRORE!
# MA se la tupla contiene oggetti mutabili...
tupla_con_lista = (1, 2, [3, 4])
tupla_con_lista[2][0] = 999 # OK! Modifichi la lista, non la tupla
print(tupla_con_lista) # (1, 2, [999, 4])
# Le coordinate non devono cambiare → usa tuple!
roma = (41.9028, 12.4964, "Roma")
milano = (45.4642, 9.1900, "Milano")
napoli = (40.8518, 14.2681, "Napoli")
citta = [roma, milano, napoli]
for lat, lon, nome in citta:
print(f"{nome}: Lat {lat}, Lon {lon}")
# Calcolare distanza media dalla prima città
lat_roma, lon_roma, _ = roma # _ ignora il valore
for lat, lon, nome in citta[1:]:
distanza_approx = ((lat - lat_roma)**2 + (lon - lon_roma)**2)**0.5
print(f"Distanza approssimativa da Roma a {nome}: {distanza_approx:.2f}°")
3. Set (Insiemi)
🎯Set: collezioni di elementi unici
I set sono collezioni non ordinate di elementi unici. Non permettono duplicati e non hanno indici. Sono perfetti per operazioni matematiche sugli insiemi (unione, intersezione, differenza) e per eliminare duplicati.
3.1 Creare set
# Set con graffe
numeri = {1, 2, 3, 4, 5}
frutti = {"mela", "banana", "arancia"}
# Set da lista (elimina duplicati automaticamente!)
lista_con_duplicati = [1, 2, 2, 3, 3, 3, 4]
set_unici = set(lista_con_duplicati)
print(set_unici) # {1, 2, 3, 4}
# Set da stringa (caratteri unici)
caratteri = set("hello")
print(caratteri) # {'h', 'e', 'l', 'o'}
# Set vuoto (NON usare {}, sono i dizionari!)
vuoto = set()
# Set non ordinato: l'ordine può variare!
print({3, 1, 2}) # Potrebbe stampare {1, 2, 3} o altro ordine
non_set = {} # Questo è un DIZIONARIO vuoto!
print(type(non_set)) # <class 'dict'>
set_corretto = set() # Questo è un SET vuoto
print(type(set_corretto)) # <class 'set'>
3.2 Operazioni con set
numeri = {1, 2, 3, 4, 5}
# Aggiungere elemento
numeri.add(6)
print(numeri) # {1, 2, 3, 4, 5, 6}
# Aggiungere elemento già presente (non ha effetto)
numeri.add(3)
print(numeri) # {1, 2, 3, 4, 5, 6} - nessun duplicato!
# Rimuovere elemento
numeri.remove(4) # Solleva errore se non esiste
numeri.discard(10) # Non solleva errore se non esiste
# Membership (molto veloce nei set!)
print(3 in numeri) # True
# Lunghezza
print(len(numeri))
# Svuotare
numeri.clear()
# Iterazione (ordine non garantito!)
colori = {"rosso", "verde", "blu"}
for colore in colori:
print(colore)
3.3 Operazioni matematiche sugli insiemi
a = {1, 2, 3, 4, 5}
b = {4, 5, 6, 7, 8}
# Unione (tutti gli elementi di entrambi)
unione = a | b # Oppure: a.union(b)
print(unione) # {1, 2, 3, 4, 5, 6, 7, 8}
# Intersezione (elementi comuni)
intersezione = a & b # Oppure: a.intersection(b)
print(intersezione) # {4, 5}
# Differenza (elementi in a ma non in b)
differenza = a - b # Oppure: a.difference(b)
print(differenza) # {1, 2, 3}
# Differenza simmetrica (elementi in a o b ma non in entrambi)
diff_simmetrica = a ^ b # Oppure: a.symmetric_difference(b)
print(diff_simmetrica) # {1, 2, 3, 6, 7, 8}
# Verifica sottoinsieme
c = {1, 2, 3}
print(c.issubset(a)) # True (c è contenuto in a)
print(a.issuperset(c)) # True (a contiene c)
# Verifica disgiunti
d = {10, 11}
print(a.isdisjoint(d)) # True (nessun elemento comune)
Visualizzazione operazioni insiemi
A = {1, 2, 3, 4, 5} B = {4, 5, 6, 7, 8}
Unione (A | B): {1, 2, 3, 4, 5, 6, 7, 8}
Intersezione (A & B): {4, 5}
Differenza (A - B): {1, 2, 3}
Differenza simmetrica (A ^ B): {1, 2, 3, 6, 7, 8}
# Studenti iscritti a diversi corsi
python = {"Alice", "Bob", "Carlo", "Diana"}
java = {"Bob", "Elena", "Franco", "Diana"}
javascript = {"Alice", "Elena", "Giorgio"}
# Studenti che seguono sia Python che Java
entrambi = python & java
print(f"Studenti in Python E Java: {entrambi}")
# Studenti che seguono Python o Java (o entrambi)
almeno_uno = python | java
print(f"Studenti in Python O Java: {almeno_uno}")
# Studenti solo in Python (non in Java)
solo_python = python - java
print(f"Solo Python: {solo_python}")
# Studenti che seguono Python o Java ma non entrambi
uno_o_altro = python ^ java
print(f"Python O Java (ma non entrambi): {uno_o_altro}")
# Tutti gli studenti unici
tutti_studenti = python | java | javascript
print(f"\nTotale studenti: {len(tutti_studenti)}")
print(f"Lista: {sorted(tutti_studenti)}") # sorted() crea lista ordinata
4. Dizionari (Dictionary)
📖Dizionari: coppie chiave-valore
I dizionari sono collezioni di coppie chiave-valore. Permettono di associare a ogni chiave unica un valore. Sono incredibilmente veloci per la ricerca e perfetti per rappresentare dati strutturati (come oggetti JSON).
4.1 Creare dizionari
# Dizionario con graffe
studente = {
"nome": "Marco",
"età": 20,
"corso": "Informatica",
"media": 27.5
}
# Dizionario vuoto
vuoto = {}
altro_vuoto = dict()
# Creare con dict()
persona = dict(nome="Lucia", età=25, città="Milano")
# Dizionario da liste di tuple
coppie = [("a", 1), ("b", 2), ("c", 3)]
dizionario = dict(coppie) # {'a': 1, 'b': 2, 'c': 3}
# Le chiavi possono essere di tipi diversi
misto = {
"nome": "Test",
42: "numero",
(1, 2): "tupla come chiave",
True: "booleano"
}
Le chiavi devono essere immutabili:
- ✅ Possono essere: stringhe, numeri, tuple
- ❌ NON possono essere: liste, set, altri dizionari
# OK
d = {"nome": "Marco", 123: "valore", (1,2): "tupla"}
# ERRORE!
# d = {[1, 2]: "lista"} # TypeError!
4.2 Accedere e modificare valori
studente = {
"nome": "Marco",
"età": 20,
"corso": "Informatica"
}
# Accesso con []
nome = studente["nome"] # "Marco"
eta = studente["età"] # 20
# Accesso sicuro con get() (non solleva errore se chiave mancante)
corso = studente.get("corso") # "Informatica"
voto = studente.get("voto", 0) # 0 (valore di default se chiave mancante)
# Modificare valore
studente["età"] = 21
# Aggiungere nuova coppia chiave-valore
studente["anno"] = 2
studente["voto"] = 28
print(studente)
# Verificare esistenza chiave
if "nome" in studente:
print(f"Lo studente si chiama {studente['nome']}")
# Numero di coppie
print(f"Numero di informazioni: {len(studente)}")
4.3 Metodi dei dizionari
Restituisce tutte le chiavi
chiavi = d.keys()
Restituisce tutti i valori
valori = d.values()
Restituisce coppie (chiave, valore)
coppie = d.items()
Ottiene valore in modo sicuro
val = d.get("k", 0)
Rimuove e restituisce valore
val = d.pop("chiave")
Rimuove ultima coppia inserita
k, v = d.popitem()
Aggiorna con altro dizionario
d.update({"a": 1})
Svuota il dizionario
d.clear()
Crea copia del dizionario
nuovo = d.copy()
Ottiene o imposta valore default
d.setdefault("k", 0)
4.4 Iterare dizionari
voti = {
"matematica": 28,
"fisica": 25,
"programmazione": 30,
"inglese": 27
}
# Iterare sulle chiavi
print("Materie:")
for materia in voti: # Oppure: for materia in voti.keys()
print(f" - {materia}")
# Iterare sui valori
print("\nVoti:")
for voto in voti.values():
print(f" {voto}")
# Iterare su coppie chiave-valore (più comune!)
print("\nVoti per materia:")
for materia, voto in voti.items():
print(f" {materia}: {voto}")
# Dizionario comprehension
voti_quadrati = {materia: voto**2 for materia, voto in voti.items()}
voti_alti = {m: v for m, v in voti.items() if v >= 27}
rubrica = {
"Mario Rossi": "333-1234567",
"Laura Bianchi": "347-9876543",
"Giovanni Verdi": "320-5551234"
}
print("=== RUBRICA TELEFONICA ===\n")
# Aggiungere contatto
rubrica["Anna Neri"] = "349-1112222"
# Cercare numero
nome = "Mario Rossi"
if nome in rubrica:
print(f"Numero di {nome}: {rubrica[nome]}")
# Modificare numero
rubrica["Laura Bianchi"] = "347-0000000"
# Visualizzare tutta la rubrica
print("\nContatti:")
for nome, numero in sorted(rubrica.items()): # Ordine alfabetico
print(f" {nome}: {numero}")
# Contare contatti
print(f"\nTotale contatti: {len(rubrica)}")
# Rimuovere contatto
del rubrica["Giovanni Verdi"]
# Oppure: numero_rimosso = rubrica.pop("Giovanni Verdi")
# Cercare in modo sicuro
numero = rubrica.get("Paolo Gialli", "Non trovato")
print(f"\nNumero Paolo: {numero}")
4.5 Dizionari annidati
# Dizionario di dizionari
studenti = {
"S001": {
"nome": "Marco",
"età": 20,
"voti": [28, 30, 27]
},
"S002": {
"nome": "Laura",
"età": 21,
"voti": [30, 29, 30]
},
"S003": {
"nome": "Giovanni",
"età": 19,
"voti": [25, 26, 27]
}
}
# Accedere a dati annidati
print(studenti["S001"]["nome"]) # "Marco"
print(studenti["S002"]["voti"][0]) # 30
# Iterare dizionario annidato
for matricola, info in studenti.items():
nome = info["nome"]
media = sum(info["voti"]) / len(info["voti"])
print(f"{nome} (Matricola: {matricola})")
print(f" Media voti: {media:.1f}")
print()
5. Quale struttura usare?
Usa LISTE quando:
- Hai una collezione ordinata
- Devi modificare elementi
- Permetti duplicati
- Accesso per posizione/indice
Esempio: playlist, cronologia, punteggi partite
Usa TUPLE quando:
- Dati che non devono cambiare
- Restituire valori multipli
- Chiavi di dizionari
- Performance importante
Esempio: coordinate, date, configurazioni
Usa SET quando:
- Elementi devono essere unici
- Ordine non importante
- Operazioni insiemistiche
- Membership test veloce
Esempio: tag, permessi utente, ID univoci
Usa DIZIONARI quando:
- Associazione chiave-valore
- Ricerca veloce per chiave
- Dati strutturati
- Contatori o raggruppamenti
Esempio: configurazioni, contatti, cache, JSON
6. Programmi completi di esempio
inventario = {
"P001": {"nome": "Laptop", "prezzo": 899.99, "quantità": 15},
"P002": {"nome": "Mouse", "prezzo": 19.99, "quantità": 50},
"P003": {"nome": "Tastiera", "prezzo": 49.99, "quantità": 30},
"P004": {"nome": "Monitor", "prezzo": 199.99, "quantità": 20}
}
print("=== GESTIONE INVENTARIO ===\n")
# Visualizzare inventario
print("PRODOTTI DISPONIBILI:")
for codice, info in inventario.items():
print(f"{codice}: {info['nome']}")
print(f" Prezzo: €{info['prezzo']:.2f}")
print(f" Quantità: {info['quantità']}")
print()
# Calcolare valore totale inventario
valore_totale = sum(p['prezzo'] * p['quantità'] for p in inventario.values())
print(f"Valore totale inventario: €{valore_totale:.2f}\n")
# Vendere prodotto
codice_venduto = "P002"
quantità_venduta = 5
if codice_venduto in inventario:
prodotto = inventario[codice_venduto]
if prodotto['quantità'] >= quantità_venduta:
prodotto['quantità'] -= quantità_venduta
totale = prodotto['prezzo'] * quantità_venduta
print(f"✅ Venduti {quantità_venduta} x {prodotto['nome']}")
print(f" Totale: €{totale:.2f}")
print(f" Rimanenti: {prodotto['quantità']}")
else:
print(f"❌ Quantità insufficiente!")
else:
print(f"❌ Prodotto non trovato!")
print()
# Prodotti in esaurimento
print("⚠️ PRODOTTI IN ESAURIMENTO (< 20):")
for codice, info in inventario.items():
if info['quantità'] < 20:
print(f" {info['nome']}: {info['quantità']} pezzi")
# Aggiungere nuovo prodotto
nuovo_codice = "P005"
inventario[nuovo_codice] = {
"nome": "Webcam",
"prezzo": 79.99,
"quantità": 25
}
print(f"\n✅ Aggiunto nuovo prodotto: {inventario[nuovo_codice]['nome']}")
def analizza_testo(testo):
"""Analizza frequenza parole in un testo"""
# Pulire e normalizzare testo
testo = testo.lower()
# Rimuovere punteggiatura
for carattere in ".,!?;:":
testo = testo.replace(carattere, "")
# Dividere in parole
parole = testo.split()
# Contare frequenze con dizionario
frequenze = {}
for parola in parole:
if parola in frequenze:
frequenze[parola] += 1
else:
frequenze[parola] = 1
# Oppure usa il metodo get:
# frequenze[parola] = frequenze.get(parola, 0) + 1
return frequenze
# Testo di esempio
testo = """
Python è un linguaggio di programmazione fantastico.
Python è facile da imparare e Python è molto potente.
Con Python puoi fare molte cose interessanti.
"""
print("=== ANALISI TESTO ===\n")
print(f"Testo:\n{testo}\n")
frequenze = analizza_testo(testo)
# Numero totale di parole
totale_parole = sum(frequenze.values())
print(f"Parole totali: {totale_parole}")
print(f"Parole uniche: {len(frequenze)}\n")
# Parole più frequenti
print("FREQUENZA PAROLE:")
for parola, frequenza in sorted(frequenze.items(), key=lambda x: x[1], reverse=True):
print(f" {parola}: {frequenza}")
print("\n" + "="*40)
# Parole che appaiono più di 2 volte
parole_frequenti = {p: f for p, f in frequenze.items() if f > 2}
print(f"\nParole che appaiono più di 2 volte: {parole_frequenti}")
1. Qual è la principale differenza tra liste e tuple?
2. Quale struttura dati NON permette duplicati?
3. Come accedi al valore di una chiave "nome" in un dizionario?
4. Cosa restituisce [1, 2, 3][1:3]?
5. Quale operatore restituisce l'intersezione tra due set?
6. Cosa succede con lista = [1, 2]; copia = lista; copia[0] = 99?
7. Esercizi pratici
Esercizio 1 - Liste: Scrivi un programma che chieda 5 numeri all'utente, li memorizzi in una lista e calcoli la media, il minimo e il massimo.
Esercizio 2 - Tuple: Crea una tupla di coordinate (x, y, z) e scrivi un programma che calcoli la distanza dall'origine (0, 0, 0).
Esercizio 3 - Set: Date due liste di numeri, trova gli elementi comuni e gli elementi presenti solo nella prima lista usando i set.
Esercizio 4 - Dizionari: Crea un dizionario che rappresenti uno studente con nome, età, corso e lista di voti. Calcola la media dei voti.
Esercizio 5 - Medio: Scrivi un programma che conti quante volte appare ogni carattere in una stringa usando un dizionario.
Esercizio 6 - Medio: Crea una lista di dizionari che rappresentino prodotti (nome, prezzo, quantità). Calcola il valore totale dell'inventario.
Esercizio 7 - Avanzato: Implementa un sistema di voto: permetti agli utenti di votare candidati (senza duplicati) e mostra i risultati finali ordinati per numero di voti.
Esercizio 8 - Sfida: Scrivi un programma che trovi tutti gli anagrammi in una lista di parole usando dizionari e set (due parole sono anagrammi se hanno le stesse lettere in ordine diverso).
8. Best Practices
- Scegli la struttura giusta: Non usare sempre liste per tutto!
- Usa tuple per dati immutabili: Coordinate, configurazioni, chiavi
- Set per membership test: Verifica
x in setè molto più veloce dix in lista - Dizionari per lookup: Cercare per chiave è velocissimo
- List comprehension per creare liste: Più leggibile e veloce
- get() per dizionari: Evita errori con chiavi mancanti
- Non modificare durante iterazione: Crea prima una copia
- Usa copy() per copie reali: Evita modifiche inaspettate
Ora che conosci le strutture dati, sei pronto per:
- Funzioni personalizzate e scope delle variabili
- Lavorare con file (lettura/scrittura)
- Moduli e import di librerie
- Gestione degli errori (try-except)
- Programmazione orientata agli oggetti